package com.xch.sboot.service.common;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.RandomUtil;
import com.xch.sboot.common.exception.BusinessException;
import com.xch.sboot.common.generator.ULIDGenerator;
import com.xch.sboot.common.util.DateUtil;
import com.xch.sboot.persistence.domain.common.File;
import com.xch.sboot.persistence.repository.common.FileRepository;
import com.xch.sboot.service.common.dto.FileDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author xch
 * 2022/12/30 15:22
 */
@Service
@Slf4j
public class FileService {

    @Value("${file.path}")
    private String rootPath;

    @Resource
    private FileRepository fileRepository;

    public FileDTO storeFile(byte[] content, String originalFilename, String contentType) {
        // 获取文件后缀 生成目录路径
        // 配置文件里的file.path + yyyyMMdd 格式组成文件夹路径
        String folder = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DateUtil.DATE_FORMAT));
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        // 保存文件并返回文件名
        String ulid = ULIDGenerator.ULID();
        String fileName = ulid + suffix;
        String filePath = rootPath + folder + java.io.File.separatorChar;
        storeFileWithFileName(content, filePath, fileName);
        //文件全路径
        String fullpath = filePath + fileName;
        // 入库
        File file = new File();
        file.setId(ulid);
        file.setContentType(contentType);
        file.setFilename(fileName);
        file.setSuffix(suffix);
        file.setFullpath(fullpath);
        file.setOldname(originalFilename);
        file.setDelFlag(Boolean.FALSE);
        fileRepository.save(file);
        return new FileDTO(file);
    }

    public void storeFileWithFileName(byte[] content, String path, String fileName) {
        // 目录不存在则创建
        java.io.File file = new java.io.File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        try (FileOutputStream os = new FileOutputStream(path + fileName);
             ByteArrayInputStream is = new ByteArrayInputStream(content)) {
            IoUtil.copy(is, os);
        } catch (IOException e) {
            log.error("FileService storeFileWithFileName error:{}", e.getMessage());
        }
    }

    private String genAccessUrl(String folder, String name) {
        return rootPath + folder + java.io.File.separatorChar + name;
    }

    public File getFileData(String id) {
        return fileRepository.findById(id).orElseThrow(() -> new BusinessException("文件不存在！"));
    }

    public void getFileStream(String fullpath, OutputStream os) throws IOException {
        try (InputStream inputStream = new FileInputStream(fullpath)) {
            int length;
            byte[] bytes = new byte[1024];
            while ((length = inputStream.read(bytes)) != -1) {
                os.write(bytes, 0, length);
            }
            os.flush();
        }
    }
}
